/**
  @file: Utils.java
  
   PURPOSE:
      This class is a collection of useful functions.
   
   @author Ron Williams
  
   REVISION HISTORY ABSTRACT
  
   PROGRAMMER:  Ron Williams ORG: MSE
  
   Copyright 2011 Mission Solutions LLC. All rights reserved.
  
   END ABSTRACT
 */

package com.mse.utilities;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.lang.Integer;
import java.lang.String;
import java.lang.StringBuilder;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
   DESCRIPTION:
      The Utils provide some common features, useful across areas.
 */
public class Utils {

   /**
      DESCRIPTION:
         determine if a name string has valid characters, suitable for use
         as the name of a directory or file. We limit the characters we
         support to: A-Z a-z 0-9 _ - ' ', and '-' must not be the first
         character!

      @param name - the name containing the text (assumed to not be blank!)
      @return boolean - true if the name contains valid characters
                        false otherwise
    */
   public static boolean isNameSuitable(String name) {
      String pattern = "[\\w -]+";  // "word" characters and ' ', '-'

      if ('-' == name.charAt(0)) {
         return false;     // we do not permit '-' as first character!
      }
      return name.matches(pattern);
   }

   /**
      DESCRIPTION:
         determine if a name string has valid characters, for use
         as the name of a directory or file. We conservatively limit the
         characters we support to: "A-Z a-z 0-9 _ -", and '-' must not be the
         first character!

      @param name - the name containing the text (assumed to not be blank!)
      @return boolean - true if the name contains valid characters
                        false otherwise
    */
   public static boolean isFileSystemName(String name) {
      String pattern = "[\\w-]+";  // "word" characters and '-'

      if ('-' == name.charAt(0)) {
         return false;     // we do not permit '-' as first character!
      }
      return name.matches(pattern);
   }

   /**
      DESCRIPTION:
         convert a name string to a suitable form for use as the name of a
         directory or file. We assume the characters of the name are "suitable"
         and just convert them by replacing 'space' characters with underscore.

         (You should have called "isNameSuitable" before this.)

      @param name    - the name containing the text to convert
      @return fsName - a file system suitable name
    */
   public static String asFSName(String name) {
      String fsName = name.replace(' ', '_');
      return fsName;
   }

   /**
      DESCRIPTION:
         convert version data to a suitable form for use as the name of a
         directory or file. (simply insert underscore between each item, to
         yield "major_minor_build")

      @param major - the major version number
      @param minor - the minor version number
      @param build - the build version number
      @return fsName - a file system suitable name
    */
   public static String asFSName(Integer major, Integer minor, Integer build) {
      StringBuilder sb = new StringBuilder();

      sb.append(major);
      sb.append("_");
      sb.append(minor);
      sb.append("_");
      sb.append(build);
      return sb.toString();
   }
   
   /**
     DESCRIPTION:
     This method creates a zip archive file containing the specified files.

     @param zipFile the name of the zip archive file to create.
     @param files array of files to archive.
     @param withPaths boolean indicating whether to include path information 
            in the zip file.
     @throws IOException if zip file creation fails.
    */
   public static void createZipFile(File zipFile, File[] files, boolean withPaths)
   throws IOException {

      // create the zip file
      ZipOutputStream zip = new ZipOutputStream(new FileOutputStream(zipFile));

      byte[] buf = new byte[2048];
      boolean success = false;

      try {

         // add each file to the zip
         for (File file : files) {

            // open a file for reading
            FileInputStream in = new FileInputStream(file);

            try {
               // add an entry for the file to the zip
               if (withPaths) {
                  zip.putNextEntry(new ZipEntry(file.getPath()));
               } else {
                  zip.putNextEntry(new ZipEntry(file.getName()));
               }

               // read data from the file and write it to the zip
               int len;
               while ((len=in.read(buf)) > 0) {
                  zip.write(buf,0,len);
               }
            } finally {
               in.close();
               zip.closeEntry();
            }
         }

         // done!
         success = true;

      } finally {
         zip.close();
         if (!success) zipFile.delete();
      }

   }

}

